package cn.mrcode.fd.blog.task;

import cn.mrcode.fd.blog.buutil.BeanUtil;
import cn.mrcode.fd.blog.cache.service.IArticleCache;
import cn.mrcode.fd.blog.cache.service.IUserCache;
import cn.mrcode.fd.blog.cache.service.impl.ArticleCacheImpl;
import cn.mrcode.fd.blog.cache.service.impl.UserCacheImpl;
import cn.mrcode.fd.blog.dao.mapper.ArticleMapper;
import cn.mrcode.fd.blog.dao.mapper.UserMapper;
import cn.mrcode.fd.blog.dto.stat.Stat;
import cn.mrcode.fd.blog.dto.stat.StatCal;
import cn.mrcode.fd.blog.entity.Article;
import cn.mrcode.fd.blog.entity.BlogConfig;
import cn.mrcode.fd.blog.entity.User;
import cn.mrcode.fd.blog.entityCu.BlogConfigCu;
import cn.mrcode.fd.blog.entityCu.UserCu;
import cn.mrcode.fd.blog.services.IArticleService;
import cn.mrcode.fd.blog.services.IBlogConfigService;
import cn.mrcode.fd.utils.log.track.LogTrackTemplateUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * 文章访问统计汇总数据 清理task
 * @author : zhuqiang
 * @version : V1.0
 * @date : 2016/1/25 21:20
 */
public class StatHzCleanTask implements Runnable {
    private static Logger LOG = LoggerFactory.getLogger(TagHanderTask.class);
    private static IArticleService iArticleService = BeanUtil.beans.getBean(IArticleService.class);
    private static IBlogConfigService iBlogConfigService = BeanUtil.beans.getBean(IBlogConfigService.class);
    private static ArticleMapper articleMapper = BeanUtil.beans.getBean(ArticleMapper.class);
    private static HashMap<String, StatCal> swapMap = new HashMap<>();
    private static String apiName = "[统计汇总数据清理task]";
    private static IArticleCache iArticleCache = BeanUtil.beans.getBean(ArticleCacheImpl.class);
    private static IUserCache iUserCache = BeanUtil.beans.getBean(UserCacheImpl.class);
    private static UserMapper userMapper = BeanUtil.beans.getBean(UserMapper.class);

    @Override
    public void run() {
        LOG.info(LogTrackTemplateUtil.svStart(apiName));

        for (; ; ) {
            try {
                ConcurrentHashMap<String, StatCal> hz = StatTask.hz;
                if (MapUtils.isNotEmpty(hz)) {
                    clean(hz);
                }
//                TimeUnit.MINUTES.sleep(3); //3分钟扫描一次数据
                TimeUnit.SECONDS.sleep(60);
                LOG.info(LogTrackTemplateUtil.svMsg(apiName, "任务正常巡查中..."));

            } catch (InterruptedException e) {
                LOG.error(LogTrackTemplateUtil.svMsg(apiName, "出错:%s", e.getMessage()));
            }
        }
    }

    /**
     * 清理操作
     * @param hz
     */
    public static void clean(ConcurrentHashMap<String, StatCal> hz) {
        swapMap.clear();
        swapMap.putAll(hz);
        hz.clear();

        for (Map.Entry<String, StatCal> ent : swapMap.entrySet()) {
            StatCal st = ent.getValue();
            int type = st.getType();
            switch (type) {
                case Stat.TYPE_READNUM:
                    cleanArticle(st);
                    break;
                case Stat.TYPE_BLOG_VISITS_NUM:
                    cleanUsers(st);
                    break;
                default:
                    LOG.info(LogTrackTemplateUtil.svMsg(apiName, "不支持的统计类型=%s", JSONObject.toJSONString(st)));
            }
        }
    }

    /**
     * 清理保存用户博客访问总量
     * @param st
     */
    private static void cleanUsers(StatCal st) {
        String id = st.getId();
        BlogConfig bc = iBlogConfigService.findBlogConfig(id);
        if (bc == null) {
            LOG.info(LogTrackTemplateUtil.svMsg(apiName, "未找到对应的博客=%s", JSONObject.toJSONString(st)));
            return;
        }

        Integer visitsNum = st.getCount();
        Long todayVisitsNum = bc.getTodayVisitsNum();
        Long totalVisitsNum = bc.getTotalVisitsNum();

        Long _todayVisitsNum = todayVisitsNum + visitsNum;
        Long _totalVisitsNum = totalVisitsNum + visitsNum;

        BlogConfig blogConfig = new BlogConfig();
        blogConfig.setId(id);
        blogConfig.setTodayVisitsNum(_todayVisitsNum);
        blogConfig.setTotalVisitsNum(_totalVisitsNum);
        iBlogConfigService.updateByPrimaryKeySelective(blogConfig);
        bc.setTodayVisitsNum(_todayVisitsNum);
        bc.setTotalVisitsNum(_totalVisitsNum);

        if (_totalVisitsNum > 10) {
            UserCu userCu = getUserCu(bc);
            iUserCache.upTotalTop(userCu);
        }
        if (_todayVisitsNum > 1) {
            UserCu userCu = getUserCu(bc);
            iUserCache.upTodayTop(userCu);
        }
    }

    private static UserCu getUserCu(BlogConfig bc) {
        User user = userMapper.selectByPrimaryKey(bc.getUserId());
        UserCu userCu = new UserCu();
        BeanUtils.copyProperties(user,userCu);
        BlogConfigCu blogConfigCu = new BlogConfigCu();
        BeanUtils.copyProperties(bc,blogConfigCu);
        userCu.setBlogConfig(blogConfigCu);
        userCu.setBlogShow(blogConfigCu.getBlogShow());
        return userCu;
    }

    /**
     * 清理保存文章访问量
     * @param statCal
     */
    private static void cleanArticle(StatCal statCal) {
        Integer readNum = statCal.getCount();
        String id = statCal.getId();
        Article article = iArticleService._findById(id);
        if (article == null) {
            return;
        }
        Long oldReadNum = article.getReadNum();
        Article record = new Article();
        record.setId(id);
        long newReadNum = readNum + oldReadNum;
        record.setReadNum(newReadNum);
        articleMapper.updateByPrimaryKeySelective(record);
        article.setReadNum(newReadNum);
        if (oldReadNum > 50) {
            iArticleCache.upAllTop(article);
        }
        if(oldReadNum > 1){
            iArticleCache.addWeekHotTop(article);
        }
        iArticleCache.upWeekNewest(article);
        iArticleCache.upWeekHotTop(article);
    }
}
